iT邦幫忙

2023 iThome 鐵人賽

DAY 7
0
AI & Data

Fast ai 30天系列 第 7

用線性模型跟神經網路來玩鐵達尼號數據(一)

  • 分享至 

  • xImage
  •  

課程網址
講師notebook
鐵達尼比賽

鐵達尼比賽就是提供乘客的個資,藉此來預測哪一種人存活率最高
例如老人女人小孩都有可能優先被排在救生艇,男人比較有英雄主義或是單身狗無牽無掛
就會先讓別人先上~當然我們不能做這麼粗淺的判斷
這也是kaggle 中的一個老比賽,算是資料科學入門的資料集

以下會分幾個階段來進行

  • 清理數據
  • 設定線性模型
  • 梯度下降
  • 訓練模型
  • 衡量準確度
  • 使用sigmoid

這是老師筆記中的大綱
因為常常跟著老師的notebook 走的話,會有點不知道我們正在幹麻
所以還是介紹一下,一般機學習的步驟

  1. 定義問題
    一開始就像前面的NLP 大賽,我們要先搞清楚我們要解決什麼問題?
    是分類,還是迴歸?
    這邊明顯這是一個二元分類問題,我們要預測哪些乘客在鐵達尼號災難中生存下來(1表示生存,0表示未生存)。
    那知道問題了後,我們就要去問,欸,那你能提供什麼資料給我?
  2. 數據探索和理解
    所以我們拿到數據之後,要先做EDA (探索性分析)
    通常資料不會太小,但是我們可以查看數據的前幾行,就可以大概觀測一下資料長什麼樣子。
    根據前面NLP的例子,我們還可以利用一些描途性統計指標來看數據,例如平均值、標準差、最大值、最小值等。
    也可以使用圖表和視覺化工具來可視化數據,例如直方圖、散點圖、箱形圖等。
  3. 數據預處理
    知道長怎樣之後,我們的資料不一定是很「乾淨」的,或是我們要拿來處理的欄位,不如我們的預期(就像sex 是男/女,我們沒辦法做計算,必需先做二值化轉成0/1),又或者有缺,又或是2個欄位要經過計算合併成某一個欄位(如同前面NLP 做的input)
    以下整理常見的數據預處理步驟
  • 缺失值處理:處理數據中的缺失值,可以通過填充平均值、中位數或使用其他方法來處理。
  • 特徵工程:根據數據的特性創建新的特徵,例如從姓名中提取稱謂(如先生、女士)。
  • 數據轉換:將類別變數轉換為數值變數,以便模型能夠處理。
  • 數據標準化或正規化:確保不同特徵的值具有相似的範圍。
  1. 模型訓練
    把資料處理好後,就開始來train 我們的model 了。(硬要講英文,但大家好像都這樣中英夾雜XDDD)
  • 選擇模型:我們可以按照不同需求去選擇模型,一開始可以先選擇快又小的,之後再按照優化步驟來選擇不同模型
  • 拆分數據:驗證集的拆分也是蠻有技巧的,一個好的驗證集拆分可以讓我們的模型可具有泛用性。
  • 模型訓練:把拆好的數據餵進模型開始訓練
  • 模型評估:使用驗證集來評估模型的性能
  1. 優化
    訓練好之後會得到結果,這後面肯定會想說
    我該怎麼優化?
    以模型優化來說,就有以下選擇
  • 超參數調整:調整模型的超參數,例如學習率、正則化參數等,以找到最佳參數組合,這個就有很多工具可以選
  • 特徵選擇:特徵要是選得好,模型不用太強也可以得到很好的結果,所以怎麼做特徵工程也是很重要的。
  • 模型選擇:就是換模型啦
  1. 預測和評估
    最後就是拿來test了,根據test 的結果回頭去優化我們的步驗。

有了概念就知道,我們一開始要先知道題目是什麼,然後就要知道資料長啥樣

這邊貼心再附一次老師的notebook

鐵達尼比賽
https://ithelp.ithome.com.tw/upload/images/20230922/20110579YHPHMMyftM.png
最重要的就是否存活,這也是我們要預測的,那其他欄位就看kaggle 的解釋,有些特別的kaggle 的解釋,例如兄弟姊妹關係,哪個港口,住什麼等級的客艙等等。

大概了解欄位之後,我們就要來看看資料是否「乾淨」

有沒有缺失值?

數據前處理

先來看一兩種補缺失值的方法
處理年齡(Age)的缺失值,使用中位數填充

df['Age'].fillna(df['Age'].median(), inplace=True)

處理登船港口(Embarked)的缺失值,使用眾數填充

df['Embarked'].fillna(df['Embarked'].mode()[0], inplace=True)

inplace =True 就是修改原dataframe,而不是創一個新的物件

還有很多補充缺失值的方法,在這邊講師統一選擇用眾數來補充
當然這些可以按欄位來決定怎樣補較為合理~
先來看一下dataframe 提供什麼函數來幫我們處理眾數
https://ithelp.ithome.com.tw/upload/images/20230923/201105795YYxjPy5QS.png
他會將每一列都幫我們取眾數,所以第2個row之後就不是我們要的
所以講師用df.mode().iloc[0]
來取第1個row

modes = df.mode().iloc[0]
df.fillna(modes, inplace=True)

這邊就是所有欄位都用他的眾數來填補的意思。

所以在這邊也是一個小細節:該怎麼填缺失值會更好呢?哪些欄位適合眾數?哪些適合平均?哪些又適合用標準差?優缺點各是什麼?
可以筆記一下,之後好好查更多資料來學習。

除了缺失值外,然後我們可以觀察一下特徵有沒有什麼「特性」
如果有怪怪的地方,是否也可以做一點處理
講師帶我們看了Fare這一欄(票價)
https://ithelp.ithome.com.tw/upload/images/20230923/20110579BPEFhxffQv.png

明顯的發現大家都買便宜的,極少數人買了超貴的
這些極值,在模型乘上係數的時候,就會對結果產生較大的影響
如前面提到假設我們的線是2次方程式 y= aX^2+bx+c
如果x 過大,那麼得到的y也會過大
所以講師提了一個取log 來使得資料較為平滑化的方法
如log10=1, log100=2 ,本來10跟100差90的,取log底數為10之後,就縮小到差1
https://ithelp.ithome.com.tw/upload/images/20230923/20110579fSkFEk5cRL.png
但這邊要注意,因為我們討論的是線性模型
所以這些工作就很重要
有的人會說,這些就是資料的特性阿,把他做這些「人工」處理不就也減少了資料特性?
說不定買豪華客艙的有優先使用救生艇的特權阿?
那這就跟模型的假設與設計比較相關,這個後續討論。

至少我們可以知道,做了「一些手段」對於某些「模型」有著較佳的效果

import matplotlib.pyplot as plt
import seaborn as sns

# 乘客年齡的直方圖
plt.figure(figsize=(8, 6))
sns.histplot(df['Age'], bins=30, kde=True)
plt.xlabel('Age')
plt.ylabel('Count')
plt.title('Distribution of Passenger Ages')
plt.show()
# 生存和死亡乘客的堆疊直方圖
plt.figure(figsize=(8, 6))
sns.histplot(data=df, x='Age', hue='Survived', bins=30, kde=True, multiple='stack')
plt.xlabel('Age')
plt.ylabel('Count')
plt.title('Distribution of Passenger Ages by Survival')
plt.show()

https://ithelp.ithome.com.tw/upload/images/20230923/20110579WclZFOhXqs.png

關於畫圖的方法,也可以多研究
這個圖大概能看出各年齡層死亡比例都蠻接近
比較有差異的是嬰幼兒,看得出來生存的機率很高。

把不能計算的類別編碼

有些欄位的資料是不能計算的
如sex:male/female,文字資料
pclass=1,2,3 (代表類別 ,沒有大小意義)
Embarked:哪個港口上船的,文字資料

為了處理這個問題,我們可以使用one-hot encoding,這就是說把每一個類別視為0 或1
如果有多個類別,就創造多個欄位,讓他們分別用0或1 代表
例如pclass 有3個類別,就會用3個欄位來表示,pclass_1, pclass_2,pclass_3

df = pd.get_dummies(df, columns=["Sex","Pclass","Embarked"])

https://ithelp.ithome.com.tw/upload/images/20230923/20110579aPeQmryRAf.png

可以看到我們的資料又被我們改來改去的變成新樣貌了!

自變數與應變數轉化為tensor

首先我們要先來設定目標變量(也就是應變數,個人不喜歡這個名字)是哪個欄位
沒錯,是Survived對吧

from torch import tensor

t_dep = tensor(df.Survived)

這邊我們創了一個tensor,把dataframe 轉化為tensor,用t_dep來存。

indep_cols = ['Age', 'SibSp', 'Parch', 'LogFare'] + added_cols
added_cols = ['Sex_male', 'Sex_female', 'Pclass_1', 'Pclass_2', 'Pclass_3', 'Embarked_C', 'Embarked_Q', 'Embarked_S']

t_indep = tensor(df[indep_cols].values, dtype=torch.float)

這邊把我們選取的欄位(獨立變數)也轉化為tensor,存在t_indep裡面

https://ithelp.ithome.com.tw/upload/images/20230923/20110579Lmo8UNPhfJ.png
這邊就可以看到我們的獨立變量,包含剛才的獨熱變碼後的值

接下來就開始設定模型了,下篇繼續!


上一篇
才上課五天就要打美國專利片語相似度大賽
下一篇
用線性模型跟神經網路來玩鐵達尼號數據(二)
系列文
Fast ai 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言